<?php

Raise::load('core.RaiseHelper');
Raise::load('core.IRaiseInitializable');
Raise::load('core.Url');
Raise::load('core.RaiseTypedCollection');

/**
 * RaiseUrlRoute - URL routing helper class
 * Helps to route between URL rewrites
 *
 * @author Sam-Mauris Yong <hellclanner at live dot com>
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package Raise.Core
 * @since 1.2
 */
class RaiseUrlRoute extends RaiseHelper implements IRaiseInitializable {

    const KEY = '_urlrouting_';

    /**
     * The rewritten relative-to-host URL
     * @var string|Url
     */
    private $rewrite;

    /**
     * The name of the RaisePage class to route to
     * @var string
     */
    private $actual;

    /**
     * The parameters in this routing
     * @var RaiseCollection
     */
    private $params;

    /**
     * All defined url rewriting routes for the application
     * @var RaiseTypedCollection
     * @static
     */
    private static $routes;

    /**
     * Create a new RaiseUrlRoute entry
     * @param string|Url $rw Rewrite version of the URL
     * @param string|Url $ac Actual file
     * @param RaiseCollection|array $pa (optional) Parameters of the URL route
     */
    function __construct($rw, $ac, $pa = array()){
        $this->rewrite = $rw;
        $this->actual = $ac;
        $this->params = new RaiseCollection($pa);
    }

    /**
     * Get or set the rewritten relative-to-host URL
     * @param string|Url $r (optional) If set, the new URL will be set.
     * @return string|Url
     */
    public function rewrite($r = null){
        if(func_num_args() == 1){
            $this->rewrite = $r;
        }
        return $this->rewrite;
    }

    /**
     * Get or set the name of the RaisePage class to route to
     * @param string $a (optional) If set, the new value will be set
     * @return string
     */
    public function actual($a = null){
        if(func_num_args() == 1){
            $this->actual = $a;
        }
        return $this->actual;
    }

    /**
     * Get the RaiseCollection of parameters for the route
     * @return RaiseCollection
     */
    public function params(){
        return $this->params;
    }

    /**
     * Prepares all the URL rewriting routes
     * @static
     */
    public static function initialize(){
        self::$routes = new RaiseTypedCollection('RaiseUrlRoute');
    }

    /**
     * Get all the URL rewriting routes
     * @return RaiseCollection
     * @static
     */
    public static function routes(){
        return self::$routes;
    }

    /**
     * Get a specific URL rewriting route with all the parameters prepared
     * @param string $key
     * @param RaiseCollection|array $args (optional) The arguments to be passed to the page
     * @return string
     */
    public static function route($key, $args = array()){

        $route = self::$routes->get($key);
        if($route == null){
            throw new RaiseInvalidArgumentException('The routing $key value \'' . $key . '\' was not found in the routing collection.');
        }
        $t = new RaiseTemplate($route->rewrite);
        foreach($args as $k => $a){
            $t->fields()->add($k, Url::encode($a));
        }

        return $t->parse();
    }

}


